﻿//
// Created by QU on 24-9-28.
//

#include "server/logic/LogicSystem.h"
#include "server/logic/LogicNode.h"

#include "server/logic/MSGID.h"

#include <iostream>
#include <print>

LogicSystem::LogicSystem(size_t worker_count)
{
    registAllCallbacks();
    startWorker(worker_count); // 启动多个工作线程
    std::print("LogicSystem started with {} workers\n", worker_count);
}

LogicSystem::~LogicSystem()
{
    stopWorker();
    std::print("LogicSystem stopped\n");
}

void LogicSystem::startWorker(const size_t worker_count)
{
    if (worker_count < 1)
    {
        throw std::invalid_argument("Worker_count must be greater than zero");
    }
    for (size_t i = 0; i < worker_count; ++i)
    {
        m_worker_threads.emplace_back([this](const std::stop_token& stop_token)
        {
            std::print("LogicSystem worker {} started\n", std::this_thread::get_id());
            workerThreadFunc(stop_token); // 每个线程都执行 workerThreadFunc
        });
    }
}

void LogicSystem::stopWorker()
{
    if (!m_worker_threads.empty())
    {
        for (auto& thread : m_worker_threads)
        {
            if (thread.joinable())
            {
                thread.request_stop(); // 请求所有线程停止
            }
        }

        m_condition.notify_all(); // 通知所有等待的线程

        for (auto& thread : m_worker_threads)
        {
            if (thread.joinable())
            {
                thread.join(); // 等待所有工作线程退出
            }
        }

        std::print("LogicSystem workers stopped\n");
    }
}

void LogicSystem::callBackRegister(const MSGID msg_id, const CallBackFunc& func)
{
    std::lock_guard<std::mutex> lock(m_mutex);
    m_callback_map[static_cast<uint8_t>(msg_id)] = func; // 将回调函数与 msg_id 绑定
}

void LogicSystem::registAllCallbacks()
{
    callBackRegister(MSGID::MSG_HELLO_WORLD,
                     // 这里传递的因为是std::function, 要么使用std::bind, 要么使用lambda.
                     [this](const std::shared_ptr<LogicNode>& logic_node)
                     {
                         this->helloWorldCallBack(logic_node);
                     });
}

void LogicSystem::helloWorldCallBack(const std::shared_ptr<LogicNode>& logic_node)
{
    std::cout << "LogicSystem::helloWorldCallBack()" << std::endl;
    auto session = logic_node->getSession();
    auto node = logic_node->getNode();
    std::cout << session->getUuid() << std::endl;
    std::cout << *node << std::endl;


    std::cout << "LogicSystem::helloWorldCallBack() prepare to sendNode" << std::endl;
    session->sendNode(node);
}

void LogicSystem::postNodeToQueue(const std::shared_ptr<LogicNode>& node)
{
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        m_logic_node_queue.push(node); // 将节点推入队列
    }
    m_condition.notify_one(); // 通知一个工作线程
}

// Queue Consumer worker (多个线程都会执行)
void LogicSystem::workerThreadFunc(const std::stop_token& stop_token)
{
    while (!stop_token.stop_requested())
    {
        std::shared_ptr<LogicNode> logic_node;

        {
            std::unique_lock<std::mutex> lock(m_mutex);

            // 等待直到队列非空或收到停止请求
            m_condition.wait(lock, [this, &stop_token]
            {
                return !m_logic_node_queue.empty() || stop_token.stop_requested();
            });

            if (stop_token.stop_requested()) break; // 处理停止请求

            if (!m_logic_node_queue.empty())
            {
                logic_node = m_logic_node_queue.front(); // 提取节点
                m_logic_node_queue.pop();
            }
        } // 锁的范围仅限于操作队列部分

        if (logic_node)
        {
            try
            {
                logicNodeDispatcher(logic_node); // 调用调度器处理节点
            }
            catch (const std::exception& e)
            {
                std::cerr << "Exception during logic node dispatch: " << e.what() << std::endl;
            }
        }
    }

    // 在停止请求后，处理队列中剩余的 LogicNode 对象
    std::shared_ptr<LogicNode> logic_node;
    while (true)
    {
        {
            std::unique_lock<std::mutex> lock(m_mutex);
            if (m_logic_node_queue.empty())
            {
                break;
            }
            logic_node = m_logic_node_queue.front();
            m_logic_node_queue.pop();
        }

        if (logic_node)
        {
            try
            {
                logicNodeDispatcher(logic_node);
            }
            catch (const std::exception& e)
            {
                std::cerr << "Exception during remaining logic node dispatch: " << e.what() << std::endl;
            }
        }
    }
}

// 调度函数
void LogicSystem::logicNodeDispatcher(const std::shared_ptr<LogicNode>& logic_node)
{
    const uint8_t msg_id = logic_node->getNode()->getMsgId();
    if (const auto it = m_callback_map.find(msg_id); it != m_callback_map.end())
    {
        std::invoke(it->second, logic_node);
    }
    else
    {
        std::cerr << "No callback registered for message ID: " << static_cast<int>(msg_id) << std::endl;
    }
}
